const web = document.querySelector('.web');
const randomCell = document.querySelector('.randomCell');

const MAX_X = 50;  //最大行
const MAX_Y = 50;  //最大列
let snakeArr = [{ x: 0, y: 0 }];
// 行走的方向
let direction = 'ArrowRight';
let pause = false;
//初始化
function init() {
    createSnake();
    createRandomCell();
    onKeyDown();
}

init();
//绘制蛇型
function createSnake() {
    web.querySelectorAll('.cell').forEach(item => { item.remove() });
    snakeArr.forEach(item => {
        let div = document.createElement('div');
        div.classList.add('cell');
        div.style.left = item.x * 10 + 'px';
        div.style.top = item.y * 10 + 'px';
        item.cell = div;
        web.appendChild(div);
    })
}
// 键盘事件
function onKeyDown() {
    document.addEventListener('keydown', e => {
        let { key } = e;
        switch (key) {
            case 'ArrowRight': //方向键右
                direction = key;
                move(1, 0);
                break;
            case 'ArrowLeft': //方向键左
                direction = key;
                move(-1, 0);
                break;
            case 'ArrowDown': //方向键下
                direction = key;
                move(0, 1);
                break;
            case 'ArrowUp': // 方向键上
                direction = key;
                move(0, -1);
                break;
            case 'Escape':
            case 'p':
                pause = !pause;
                pause ? clearInterval(timer) : timer = autoMove();
        }
    })
}
// 移动
function move(x, y) {
    if (isGameOver(snakeArr[0].x + x, snakeArr[0].y + y)) {
        alert('游戏结束!');
        document.querySelectorAll('.cell').forEach(item => { item.className = 'endCell' });
        snakeArr = [];
        clearInterval(timer);
        return;
    }
    // 判断第一个元素是否碰到了随机块,
    if (isEat(snakeArr[0].x + x, snakeArr[0].y + y)) {
        let lastX = snakeArr[snakeArr.length - 1].x;
        let lastY = snakeArr[snakeArr.length - 1].y;
        // 如果碰到了,在数组的末尾添加
        snakeArr.push({ x: lastX + x, y: lastY + y });
        // 重新绘制
        createSnake();
        // 重新绘制新的随机块
        createRandomCell();
    }
    //每一次移动都是往头部插入一个元素,然后将尾部的元素给删除
    snakeArr.unshift({ x: snakeArr[0].x + x, y: snakeArr[0].y + y });
    let last = snakeArr.pop();
    web.removeChild(last.cell);
    createSnake();
}
// 判断是否碰到了随机的块
function isEat(x, y) {
    let { left, top } = randomCell.style;
    let randomCellX = parseInt(left) / 10;
    let randomCellY = parseInt(top) / 10;
    if (x == randomCellX && y == randomCellY) {
        return true;
    }
    return false;
}
// 判断是否发生了触碰 来指定游戏结束
function isGameOver(x, y) {
    // 越过边界
    if (
        (direction == 'ArrowRight' && x == MAX_X) ||
        (direction == 'ArrowLeft' && x < 0) ||
        (direction == 'ArrowUp' && y < 0) ||
        (direction == 'ArrowDown' && y == MAX_Y)
    ) {
        return true;
    }
    // 如果自己碰到了自己
    for (let i = 0; i < snakeArr.length; i++) {
        if (snakeArr[i].x == x && snakeArr[i].y == y) {
            return true;
        }
    }
    return false;
}
// 绘制随机的块
function createRandomCell() {
    let { x, y } = twoRandomNum();
    randomCell.style.left = x * 10 + 'px';
    randomCell.style.top = y * 10 + 'px';
}
// 生成两个不包含所有蛇方块坐标的随机坐标
function twoRandomNum() {
    // 所有蛇方块的二维坐标数组  x_y: [[0,1],[1,1]]
    let x_y = snakeArr.map(item => [item.x, item.y]);
    let x = 0;
    let y = 0;
    let flag = false;
    while (true) {
        x = Math.floor(Math.random() * MAX_X);
        y = Math.floor(Math.random() * MAX_Y);
        for (let i = 0; i < x_y.length; i++) {
            if (x_y[i][0] == x && x_y[i][1] == y) {
                flag = false;
                break;
            } else {
                flag = true;
            }
        }
        if (flag) {
            break;
        }
    }
    return { x, y };
}
// 自动行走
let timer = autoMove();

function autoMove(){
    return setInterval(() => {
        switch (direction) {
            case 'ArrowRight': //方向键右
                move(1, 0);
                break;
            case 'ArrowLeft': //方向键左
                move(-1, 0);
                break;
            case 'ArrowDown': //方向键下
                move(0, 1);
                break;
            case 'ArrowUp': // 方向键上
                move(0, -1);
                break;
        }
    }, 200)
}